package com.dy.yunying.biz.service.sign.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.entity.hongbao.HbGiftBag;
import com.dy.yunying.api.entity.sign.SignActivity;
import com.dy.yunying.api.entity.sign.SignTaskConfigDO;
import com.dy.yunying.api.entity.sign.SignTaskGoodsDO;
import com.dy.yunying.api.req.sign.SignTaskConfigVO;
import com.dy.yunying.biz.dao.ads.hongbao.HbGiftBagMapper;
import com.dy.yunying.biz.dao.ads.sign.SignActivityMapper;
import com.dy.yunying.biz.dao.ads.sign.SignTaskConfigMapper;
import com.dy.yunying.biz.dao.ads.sign.SignTaskGoodsMapper;
import com.dy.yunying.biz.service.hongbao.HbGiftBagService;
import com.dy.yunying.biz.service.sign.SignTaskConfigService;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 *
 */
@Service
@RequiredArgsConstructor
public class SignTaskConfigServiceImpl extends ServiceImpl<SignTaskConfigMapper, SignTaskConfigDO> implements SignTaskConfigService {

	private static final Pattern GIFT_CODE_PATTERN = Pattern.compile("^[A-Za-z0-9]{3,50}$");

	private final HbGiftBagService hbGiftBagService;

	private final SignTaskGoodsMapper signTaskGoodsMapper;

	private final HbGiftBagMapper hbGiftBagMapper;

	private final SignActivityMapper signActivityMapper;

	/**
	 * 获取任务配置列表
	 *
	 * @param activityId
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public List<SignTaskConfigDO> taskConfigList(Long activityId) {
		final List<SignTaskConfigDO> taskConfigList = baseMapper.selectTaskConfigListByActivityId(activityId);
		return taskConfigList.stream().map(e -> e.setEditable(this.getTaskEditable(activityId))).collect(Collectors.toList());
	}

	// 获取任务是否可编辑状态
	private Integer getTaskEditable(Long activityId) {
		int editable = 0;
		try {
			this.getSignActivityTime(activityId, new Date());
			editable = 1;
		} catch (IllegalArgumentException ignore) {
		}
		return editable;
	}

	// 获取活动信息
	private SignActivity getSignActivityTime(Long activityId, Date now) {
		final SignActivity activityBean = signActivityMapper.selectOne(Wrappers.<SignActivity>lambdaQuery()
				.select(SignActivity::getStartTime, SignActivity::getFinishTime)
				.eq(SignActivity::getId, activityId)
				.eq(SignActivity::getActivityStatus, 1) // 状态必须是待上线
				.ge(SignActivity::getFinishTime, now) // 当前时间必须小于或等于结束时间
				.eq(SignActivity::getDeleted, 0));
		if (null == activityBean) {
			throw new IllegalArgumentException("任务所属活动状态必须为“待上线”，并且结束时间不能小于当前时间");
		}
		return activityBean;
	}

	/**
	 * 保存任务配置信息
	 *
	 * @param task
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public Pair<Integer, Integer> saveTaskConfig(SignTaskConfigVO task) {
		// 获取当前时间和当前登录用户ID
		final Date now = new Date();
		final long userId = Integer.toUnsignedLong(Objects.requireNonNull(SecurityUtils.getUser()).getId());

		final int prizeType = ObjectUtils.defaultIfNull(task.getPrizeType(), -1);
		final int giftType = ObjectUtils.defaultIfNull(task.getGiftType(), -1);
		final int cdkExpireType = ObjectUtils.defaultIfNull(task.getCdkExpireType(), -1);
		final int currencyType = ObjectUtils.defaultIfNull(task.getCurrencyType(), -1);
		final int currencyExpireType = ObjectUtils.defaultIfNull(task.getCurrencyExpireType(), -1);

		// 校验时间
		this.validTaskTime(now, task, task.getActivityId(), null);

		// 保存任务配置信息
		final SignTaskConfigDO insertBean = new SignTaskConfigDO()
				.setActivityId(task.getActivityId())
				.setTaskType(task.getTaskType())
				.setConditionType(task.getConditionType())
				.setConditionRoleRecharge(task.getConditionRoleRecharge())
				.setTaskName(this.requireTaskName(task))
				.setStartTime(task.getStartTime())
				.setEndTime(task.getEndTime())
				.setExtraBonusType(task.getExtraBonusType())
				.setExtraBonusNum(task.getExtraBonusNum())
				.setPrizeType(task.getPrizeType())
				.setGiftType(prizeType == 1 ? giftType : null)
				.setGiftCode(prizeType == 1 && giftType == 2 ? task.getGiftCode() : null)
				.setGiftAmount(prizeType == 1 && giftType == 2 ? task.getGiftAmount() : null)
				.setCdkName(prizeType == 2 ? task.getCdkName() : null)
				.setCdkAmount(prizeType == 2 ? task.getCdkAmount() : null)
				.setCdkLimitAmount(prizeType == 2 ? task.getCdkLimitAmount() : null)
				.setCdkExpireType(prizeType == 2 ? task.getCdkExpireType() : null)
				.setCdkLimitType(prizeType == 2 ? task.getCdkLimitType() : null)
				.setCdkStartTime(prizeType == 2 && cdkExpireType == 1 ? task.getCdkStartTime() : null)
				.setCdkEndTime(prizeType == 2 && cdkExpireType == 1 ? task.getCdkEndTime() : null)
				.setCdkExpireDays(prizeType == 2 && cdkExpireType == 2 ? task.getCdkExpireDays() : null)
				.setCurrencyAmount(prizeType == 3 ? task.getCurrencyAmount() : null)
				.setCurrencyType(prizeType == 3 ? task.getCurrencyType() : null)
				.setCurrencyExpireType(prizeType == 3 && currencyType == 2 ? task.getCurrencyExpireType() : null)
				.setCurrencyExpireTime(prizeType == 3 && currencyType == 2 && currencyExpireType == 1 ? task.getCurrencyExpireTime() : null)
				.setCurrencyExpireDays(prizeType == 3 && currencyType == 2 && currencyExpireType == 2 ? task.getCurrencyExpireDays() : null)
				.setDeleted(0)
				.setCreateTime(now)
				.setUpdateTime(now)
				.setCreateId(userId)
				.setUpdateId(userId);
		baseMapper.insert(insertBean);

		if (1 == prizeType) {
			// 保存物品信息
			this.batchInsertTaskGoods(task.setId(insertBean.getId()), userId, now);
			// 礼包唯一码
			if (1 == giftType) {
				// 保存礼包码信息
				return this.saveSignGiftBag(task.getGiftBagFile(), 4, insertBean.getId());
			}
		}
		return Pair.of(0, 0);
	}

	/**
	 * 修改任务配置信息
	 *
	 * @param task
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public Pair<Integer, Integer> editTaskConfig(SignTaskConfigVO task) {
		// 校验任务ID是否存在
		SignTaskConfigDO taskBean = baseMapper.selectOne(Wrappers.<SignTaskConfigDO>lambdaQuery().select(SignTaskConfigDO::getActivityId, SignTaskConfigDO::getStartTime, SignTaskConfigDO::getEndTime).eq(SignTaskConfigDO::getDeleted, 0).eq(SignTaskConfigDO::getId, task.getId()));
		if (null == taskBean) {
			return Pair.of(0, 0);
		}
		// 获取当前时间和当前登录用户ID
		final Date now = new Date();
		final long userId = Integer.toUnsignedLong(Objects.requireNonNull(SecurityUtils.getUser()).getId());

		// 校验时间范围
		task.setStartTime(null == task.getStartTime() ? taskBean.getStartTime() : task.getStartTime());
		task.setEndTime(null == task.getEndTime() ? taskBean.getEndTime() : task.getEndTime());

		final int prizeType = ObjectUtils.defaultIfNull(task.getPrizeType(), -1);
		final int giftType = ObjectUtils.defaultIfNull(task.getGiftType(), -1);
		final int cdkExpireType = ObjectUtils.defaultIfNull(task.getCdkExpireType(), -1);
		final int currencyType = ObjectUtils.defaultIfNull(task.getCurrencyType(), -1);
		final int currencyExpireType = ObjectUtils.defaultIfNull(task.getCurrencyExpireType(), -1);

		RuntimeException cause = null;
		try {

			this.validTaskTime(now, task, taskBean.getActivityId(), task.getId());

			// 修改任务配置信息
			if (ObjectUtils.anyNotNull(task.getTaskType(), task.getConditionType(), task.getConditionRoleRecharge(), task.getStartTime(), task.getEndTime(), task.getExtraBonusType(), task.getExtraBonusNum())) {
				final SignTaskConfigDO updateBean = new SignTaskConfigDO()
						.setId(task.getId())
						.setTaskType(task.getTaskType())
						.setConditionType(task.getConditionType())
						.setConditionRoleRecharge(task.getConditionRoleRecharge())
						.setTaskName(this.requireTaskName(task))
						.setStartTime(task.getStartTime())
						.setEndTime(task.getEndTime())
						.setExtraBonusType(task.getExtraBonusType())
						.setExtraBonusNum(task.getExtraBonusNum())
						.setPrizeType(task.getPrizeType())
						.setGiftType(prizeType == 1 ? giftType : null)
						.setGiftCode(prizeType == 1 && giftType == 2 ? task.getGiftCode() : null)
						.setGiftAmount(prizeType == 1 && giftType == 2 ? task.getGiftAmount() : null)
						.setCdkName(prizeType == 2 ? task.getCdkName() : null)
						.setCdkAmount(prizeType == 2 ? task.getCdkAmount() : null)
						.setCdkLimitAmount(prizeType == 2 ? task.getCdkLimitAmount() : null)
						.setCdkExpireType(prizeType == 2 ? task.getCdkExpireType() : null)
						.setCdkStartTime(prizeType == 2 && cdkExpireType == 1 ? task.getCdkStartTime() : null)
						.setCdkEndTime(prizeType == 2 && cdkExpireType == 1 ? task.getCdkEndTime() : null)
						.setCdkExpireDays(prizeType == 2 && cdkExpireType == 2 ? task.getCdkExpireDays() : null)
						.setCdkLimitType(prizeType == 2 ? task.getCdkLimitType() : null)
						.setCurrencyAmount(prizeType == 3 ? task.getCurrencyAmount() : null)
						.setCurrencyType(prizeType == 3 ? task.getCurrencyType() : null)
						.setCurrencyExpireType(prizeType == 3 && currencyType == 2 ? task.getCurrencyExpireType() : null)
						.setCurrencyExpireTime(prizeType == 3 && currencyType == 2 && currencyExpireType == 1 ? task.getCurrencyExpireTime() : null)
						.setCurrencyExpireDays(prizeType == 3 && currencyType == 2 && currencyExpireType == 2 ? task.getCurrencyExpireDays() : null)
						.setUpdateTime(now)
						.setUpdateId(userId);
				baseMapper.updateById(updateBean);
			}

			if (1 == prizeType) {
				// 删除任务下所有物品关联信息
				signTaskGoodsMapper.update(new SignTaskGoodsDO().setDeleted(1).setUpdateTime(now).setUpdateId(userId), Wrappers.<SignTaskGoodsDO>lambdaQuery().eq(SignTaskGoodsDO::getTaskId, task.getId()));
				// 保存新的物品信息
				this.batchInsertTaskGoods(task.setActivityId(taskBean.getActivityId()), userId, now);
			}
		} catch (IllegalArgumentException e) {
			if (1 == prizeType) {
				baseMapper.updateById(new SignTaskConfigDO()
						.setId(task.getId())
						.setGiftType(task.getGiftType())
						.setGiftCode(task.getGiftCode())
						.setGiftAmount(task.getGiftAmount())
						.setUpdateTime(now)
						.setUpdateId(userId));
			} else {
				cause = e;
			}
		}
		if (1 == prizeType) {
			// 礼包唯一码
			if (1 == giftType) {
				// 保存礼包码信息
				if (null == task.getGiftBagFile() || task.getGiftBagFile().isEmpty()) {
					return Pair.of(0, 0);
				}
				return this.saveSignGiftBag(task.getGiftBagFile(), 4, task.getId());
			}
		} else if (null != cause) {
			throw cause;
		}
		return Pair.of(0, 0);
	}

	private void validTaskTime(Date now, SignTaskConfigVO task, Long activityId, Long neTaskId) {
		final Date startTime = task.getStartTime(), endTime = task.getEndTime();

		final ZoneOffset offset = OffsetTime.now().getOffset();
		long currentDayOfMillis = LocalDate.now().atStartOfDay().toInstant(offset).toEpochMilli();
		long taskStartDayOfMillis = LocalDateTime.ofInstant(startTime.toInstant(), offset).toLocalDate().atStartOfDay().toInstant(offset).toEpochMilli();
		long taskEndDayOfMillis = LocalDateTime.ofInstant(endTime.toInstant(), offset).toLocalDate().atStartOfDay().toInstant(offset).toEpochMilli();

		// 开始时间不能小于当前时间
		if (taskStartDayOfMillis < currentDayOfMillis) {
			throw new IllegalArgumentException("开始时间不能小于当前时间");
		}

		// 开始时间不能大于结束时间
		if (taskStartDayOfMillis > taskEndDayOfMillis) {
			throw new IllegalArgumentException("开始时间不能大于结束时间");
		}

		// 任务开始和结束时间必须在活动时间范围内
		final SignActivity activityBean = this.getSignActivityTime(activityId, now);
		long activityStartDayOfMillis = LocalDateTime.ofInstant(activityBean.getStartTime().toInstant(), offset).toLocalDate().atStartOfDay().toInstant(offset).toEpochMilli();
		long activityEndDayOfMillis = LocalDateTime.ofInstant(activityBean.getFinishTime().toInstant(), offset).toLocalDate().atStartOfDay().toInstant(offset).toEpochMilli();
		if (taskStartDayOfMillis < activityStartDayOfMillis || taskEndDayOfMillis > activityEndDayOfMillis) {
			throw new IllegalArgumentException("任务开始和结束时间不在活动时间范围内");
		}

		// 同一活动下多个任务时间不能重复
		final LambdaQueryWrapper<SignTaskConfigDO> queryWrapper = Wrappers.<SignTaskConfigDO>lambdaQuery()
				.select(SignTaskConfigDO::getStartTime, SignTaskConfigDO::getEndTime)
				.eq(SignTaskConfigDO::getDeleted, 0)
				.eq(SignTaskConfigDO::getActivityId, activityId)
				.ne(Objects.nonNull(neTaskId), SignTaskConfigDO::getId, neTaskId)
				.orderByAsc(SignTaskConfigDO::getStartTime);
		List<SignTaskConfigDO> taskConfigList = baseMapper.selectList(queryWrapper);
		for (SignTaskConfigDO taskBean : taskConfigList) {
			long tempStartDayOfMillis = LocalDateTime.ofInstant(taskBean.getStartTime().toInstant(), offset).toLocalDate().atStartOfDay().toInstant(offset).toEpochMilli();
			long tempEndDayOfMillis = LocalDateTime.ofInstant(taskBean.getEndTime().toInstant(), offset).toLocalDate().atStartOfDay().toInstant(offset).toEpochMilli();
			if (taskStartDayOfMillis <= tempEndDayOfMillis && taskEndDayOfMillis >= tempStartDayOfMillis) {
				throw new IllegalArgumentException("当前活动下任务时间发生了重叠");
			}
		}

		final Integer prizeType = task.getPrizeType();
		if (2 == prizeType) {
			if (1 == task.getCdkExpireType() && task.getCdkStartTime().before(startTime)) {
				throw new IllegalArgumentException("代金券开始时间不能小于任务开始时间");
			}
		} else if (3 == prizeType) {
			if (2 == task.getCurrencyType() && 1 == task.getCurrencyExpireType() && task.getCurrencyExpireTime().before(startTime)) {
				throw new IllegalArgumentException("余额结束时间不能小于任务开始时间");
			}
		}

	}

	private String requireTaskName(SignTaskConfigVO task) {
		if (null != task.getConditionType() && 10 == task.getConditionType() && null != task.getConditionRoleRecharge()) {
			return String.format("当日累计充值满%d元", task.getConditionRoleRecharge());
		}
		return StringUtils.EMPTY;
	}

	private void batchInsertTaskGoods(SignTaskConfigVO task, Long userId, Date now) {
		for (int i = 0; i < task.getGoodsIds().length; ++i) {
			final SignTaskGoodsDO insertTaskGoodsBean = new SignTaskGoodsDO()
					.setActivityId(task.getActivityId())
					.setTaskId(task.getId())
					.setGoodsId(task.getGoodsIds()[i])
					.setGoodsNum(task.getGoodsNums()[i])
					.setDeleted(0)
					.setCreateTime(now)
					.setUpdateTime(now)
					.setCreateId(userId)
					.setUpdateId(userId);
			signTaskGoodsMapper.insert(insertTaskGoodsBean);
		}
	}

	/**
	 * 删除任务配置
	 *
	 * @param taskId
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public void deleteTaskConfigByTaskId(Long taskId) {
		// 校验任务ID是否存在
		SignTaskConfigDO taskBean = baseMapper.selectOne(Wrappers.<SignTaskConfigDO>lambdaQuery().select(SignTaskConfigDO::getActivityId).eq(SignTaskConfigDO::getDeleted, 0).eq(SignTaskConfigDO::getId, taskId));
		if (null == taskBean) {
			return;
		}
		// 获取当前时间和当前登录用户ID
		final Date now = new Date();
		final long userId = Integer.toUnsignedLong(Objects.requireNonNull(SecurityUtils.getUser()).getId());

		// 校验任务所属活动是否有效
		this.getSignActivityTime(taskBean.getActivityId(), now);

		// 删除任务配置
		baseMapper.updateById(new SignTaskConfigDO().setDeleted(1).setUpdateTime(now).setUpdateId(userId).setId(taskId));

		// 删除任务物品关联信息
		signTaskGoodsMapper.update(new SignTaskGoodsDO().setDeleted(1).setUpdateTime(now).setUpdateId(userId), Wrappers.<SignTaskGoodsDO>lambdaQuery().eq(SignTaskGoodsDO::getTaskId, taskId));

		// 删除任务关联的礼包码信息
		hbGiftBagMapper.delete(Wrappers.<HbGiftBag>lambdaQuery().eq(HbGiftBag::getStatus, 0).eq(HbGiftBag::getType, 4).eq(HbGiftBag::getObjectId, taskId));
	}

	/**
	 * 根据活动ID删除任务配置
	 *
	 * @param activityId
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public void deleteTaskConfigByActivityId(Long activityId) {
		// 获取当前时间和当前登录用户ID
		final Date now = new Date();
		final long userId = Integer.toUnsignedLong(Objects.requireNonNull(SecurityUtils.getUser()).getId());
		// 校验活动时间
		//this.getSignActivityTime(activityId, now);

		// 校验活动ID下是否存在任务
		List<Long> taskIdList = baseMapper.selectList(Wrappers.<SignTaskConfigDO>lambdaQuery().select(SignTaskConfigDO::getId).eq(SignTaskConfigDO::getDeleted, 0).eq(SignTaskConfigDO::getActivityId, activityId))
				.stream().map(SignTaskConfigDO::getId).collect(Collectors.toList());
		if (taskIdList.isEmpty()) {
			return;
		}

		// 删除任务配置
		baseMapper.update(new SignTaskConfigDO().setDeleted(1).setUpdateTime(now).setUpdateId(userId), Wrappers.<SignTaskConfigDO>lambdaQuery().in(SignTaskConfigDO::getId, taskIdList));

		// 删除任务物品关联信息
		signTaskGoodsMapper.update(new SignTaskGoodsDO().setDeleted(1).setUpdateTime(now).setUpdateId(userId), Wrappers.<SignTaskGoodsDO>lambdaQuery().in(SignTaskGoodsDO::getTaskId, taskIdList));

		// 删除任务关联的礼包码信息
		hbGiftBagMapper.delete(Wrappers.<HbGiftBag>lambdaQuery().eq(HbGiftBag::getStatus, 0).eq(HbGiftBag::getType, 4).in(HbGiftBag::getObjectId, taskIdList));
	}

	/**
	 * 保存礼包码信息
	 *
	 * @param giftBagFile 礼包码文件
	 * @param giftType    礼包码类型：1-红包，2-提现，3-签到奖品，4-签到任务
	 * @param objectId    来源ID
	 * @return pair.left=总上传数，pair.right=成功保存数
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public Pair<Integer, Integer> saveSignGiftBag(MultipartFile giftBagFile, Integer giftType, Long objectId) {
		// 从文件中获取有效的礼包码集合
		Pair<Set<String>, Integer> pair;
		try {
			pair = this.readGiftCodeSet(giftBagFile);
		} catch (IOException e) {
			throw new IllegalArgumentException("请上传正确的礼包码文件", e);
		}

		// 保存礼包码文件
		if (0 == pair.getLeft().size()) {
			return Pair.of(pair.getRight(), pair.getLeft().size());
		}
		final Date now = new Date();
		final long userId = Integer.toUnsignedLong(Objects.requireNonNull(SecurityUtils.getUser()).getId());
		hbGiftBagService.saveBatch(pair.getLeft().stream().map(code -> new HbGiftBag()
				.setType(giftType)
				.setObjectId(objectId)
				.setGiftCode(code)
				.setUsable(1)
				.setStatus(0)
				.setDeleted(0)
				.setCreateTime(now)
				.setUpdateTime(now)
				.setCreateId(userId)
				.setUpdateId(userId)).collect(Collectors.toSet()), 1000);

		return Pair.of(pair.getRight(), pair.getLeft().size());
	}

	private Pair<Set<String>, Integer> readGiftCodeSet(MultipartFile giftBagFile) throws IOException {

		int totalCount = 0;
		final Set<String> giftCodeSet = new HashSet<>();
		final Set<String> existsGiftCodeSet = new HashSet<>();
		final Set<String> tempGiftCodeSet = new HashSet<>();

		try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(giftBagFile.getInputStream()))) {
			for (String line; null != (line = reader.readLine()); ) {
				// 不能为空并且不能为空白字符串（需要首尾去除空白）
				if (0 == (line = line.trim()).length()) {
					continue;
				}
				++totalCount;

				// 必须为长度在在3 ~ 50之间（前后包括）的大写小写和数字字符串
				if (!GIFT_CODE_PATTERN.matcher(line).find()) {
					continue;
				}

				// 礼包码全局不能重复
				tempGiftCodeSet.add(line);
				if (tempGiftCodeSet.size() == 1000) {
					existsGiftCodeSet.addAll(this.getExistsGiftCodeList(tempGiftCodeSet));
				}

				giftCodeSet.add(line);
			}
		}
		existsGiftCodeSet.addAll(this.getExistsGiftCodeList(tempGiftCodeSet));

		giftCodeSet.removeAll(existsGiftCodeSet);
		return Pair.of(giftCodeSet, totalCount);
	}

	private Set<String> getExistsGiftCodeList(Set<String> tempGiftCodeSet) {
		if (tempGiftCodeSet.isEmpty()) {
			return Collections.emptySet();
		}
		Set<String> set = hbGiftBagMapper.selectList(Wrappers.<HbGiftBag>lambdaQuery()
				.select(HbGiftBag::getGiftCode)
				.in(HbGiftBag::getGiftCode, tempGiftCodeSet)
				.eq(HbGiftBag::getDeleted, 0))
				.stream().map(HbGiftBag::getGiftCode).collect(Collectors.toSet());
		tempGiftCodeSet.clear();
		return set;
	}

}
